﻿using System;

using SilverChart;
using SilverChart.Configuration;
using SilverChart.Components;
using SilverChart.Core.Resources;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
using SilverChart.Core.Log;
using System.Collections.Generic;
using SilverChart.Util;
using System.Windows;

namespace SilverChart.BarChart {
    public class BarChartModel : CartesianCoordinateChart {
        private static Logger logger = Logger.GetLogger(typeof(BarChartModel).FullName);
        private const Int32 XOffset = 1;
        private const Double BarWidthPercent = 0.8;
        private const Double DefaultBarHeight = 10;

        private List<Border> Bars;
        private Double allBarWidth;
        private Double barWidth;

        private BarChartConfigurationWrapper Wrapper;

        public BarChartModel(Element data)
            : base(data) {
            logger.Debug("BarChart: Init");
            Wrapper = new BarChartConfigurationWrapper(data);
            logger.Debug("BarChart Wrapper Inited");
            Bars = new List<Border>();

            CreateBars();
            logger.Debug("BarChart Inited");
        }

        private void CreateBars() {
            for (Int32 i = 0; i < Wrapper.Values.Count; i++) {
                Border bar = Wrapper.Bar;
                if (Wrapper.ShowTip) {
                    ToolTip tip = new ToolTip();
                    tip.HorizontalOffset = -5;
                    tip.VerticalOffset = -35;
                    tip.Opacity = 0.8;
                    tip.Content = Math.Round(Wrapper.Values[i], 10).ToString();

                    ToolTipService.SetToolTip(bar, tip);
                }
                Children.Add(bar);
                Bars.Add(bar);
            }
        }

        protected override Size MeasureOverride(Size availableSize) {
            IList<BarChartModel> barCharts = WidgetsManager.GetCompatibleComponents<BarChartModel>();
            Int32 barCount = barCharts.Count;

            allBarWidth = (XAxis as XAxisComponent).TickWidth * BarWidthPercent;
            //allBarWidth = allBarWidth > 100 ? 100 : allBarWidth;
            barWidth = allBarWidth / barCount;

            for (Int32 i = 0; i < Wrapper.Values.Count; i++) {
                Border bar = Bars[i];
                bar.Width = barWidth - bar.Margin.Left - bar.Margin.Right;
                bar.Width = bar.Width < 0 ? 1 : bar.Width;
                bar.Measure(new Size(barWidth, DefaultBarHeight));
            }

            Size aSize = new Size(Math.Min(availableSize.Width, 10000), Math.Min(availableSize.Height, 10000));
            return aSize;
        }

        protected override Size ArrangeOverride(Size finalSize) {
            IList<BarChartModel> barCharts = WidgetsManager.GetCompatibleComponents<BarChartModel>();
            Int32 currentChartIndex = barCharts.IndexOf(this);

            Double thisBarOffset = barWidth * currentChartIndex - allBarWidth / 2;

            for (Int32 i = 0; i < Wrapper.Values.Count; i++) {
                Double x = XAxis.MappingValueToAxis(i + XOffset);
                Double y = YAxis.MappingValueToAxis(Wrapper.Values[i]);

                Double barLeft = x + thisBarOffset;
                Double barTop = y;
                Double barHeight = finalSize.Height - y;

                Border bar = Bars[i];
                bar.Arrange(new Rect(barLeft, barTop, bar.DesiredSize.Width, barHeight));
            }
            return finalSize;
        }

        public override List<LegendProperties> Legends {
            get {
                if (Wrapper.LegendName == null || Wrapper.LegendName.Trim().Length <= 0) {
                    return null;
                }

                return new List<LegendProperties>(){
                    new LegendProperties(this, Wrapper.LegendName, Wrapper.Fill, Wrapper.Stroke)
                };
            }
        }

        public override string WidgetName {
            get {
                return "Bar Chart Model";
            }
        }
    }
}
